home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / forms / FORMS / objects.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  17KB  |  587 lines

  1. /*
  2.  * objects.c
  3.  *
  4.  * This file is part of the basis of the Forms Library
  5.  *
  6.  * It contains all basic routines that deal with objects, like making
  7.  * them, changing them, drawing them, and sending events to them.
  8.  *
  9.  * Written by Mark Overmars
  10.  *
  11.  * Version 2.2 b
  12.  * Date: Jun 18, 1993
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <sys/types.h>
  17. #include <string.h>
  18. #include "gl/gl.h"
  19. #include "gl/device.h"
  20. #include <malloc.h>
  21. #include "forms.h"
  22.  
  23. /*-----------------------------------------------------------------------
  24.    Creation routines
  25. -----------------------------------------------------------------------*/
  26.  
  27. FL_FORM *fl_make_form(float w,float h)
  28. /* Creates an empty form. NOT FOR USER. */
  29. {
  30.   FL_FORM *form;
  31.   form = (FL_FORM *) fl_malloc(sizeof(FL_FORM));
  32.   form->w = w; form->h = h;
  33.   form->window = -1;
  34.   form->deactivated = 1;
  35.   form->visible = 0;
  36.   form->frozen = 0;
  37.   form->form_call_back = NULL;
  38.   form->focusobj = NULL;
  39.   form->first = NULL;
  40.   form->last = NULL;
  41.   form->doublebuf = fl_doublebuf;
  42.   form->hotx = form->hoty = -1;
  43.   return form;
  44. }
  45.  
  46. FL_OBJECT *fl_make_object(int objclass,int type,float x,float y,
  47.             float w,float h, const char *label,FL_HANDLEPTR handle)
  48. /* Creates an object, NOT FOR USER. */
  49. {
  50.   FL_OBJECT *ob;
  51.   ob = (FL_OBJECT *) fl_malloc(sizeof(FL_OBJECT));
  52.   ob->objclass = objclass;
  53.   ob->type = type;
  54.   ob->boxtype = FL_NO_BOX;
  55.   ob->x = x; ob->y = y; ob->w = w; ob->h = h;
  56.   ob->label = (char *) fl_malloc(strlen(label)+1);
  57.   strcpy(ob->label,label);
  58.   ob->handle = handle;
  59.   ob->align = FL_ALIGN_CENTER;
  60.   ob->lcol = 0;
  61.   ob->lsize = FL_NORMAL_FONT;
  62.   ob->lstyle = FL_NORMAL_STYLE;
  63.   ob->shortcut = (char *) fl_malloc(1);
  64.   ob->shortcut[0] = '\0';
  65.   ob->pushed = 0;
  66.   ob->focus = 0;
  67.   ob->belowmouse = 0;
  68.   ob->input = 0;
  69.   ob->wantall = 0;
  70.   ob->active = 1;
  71.   ob->visible = 1;
  72.   ob->radio = 0;
  73.   ob->automatic = 0;
  74.   ob->object_call_back = NULL;
  75.   ob->spec = NULL;
  76.   ob->next = NULL;
  77.   ob->prev = NULL;
  78.   ob->form = NULL;
  79.   return ob;
  80. }
  81.  
  82. void fl_free_object(FL_OBJECT *obj)
  83. /* Frees the memory used by an object. */
  84. {
  85.   /* check whether ok to free it */
  86.   if (obj == NULL) 
  87.     { fl_error("fl_free_object","Trying to free NULL object."); return;}
  88.   if (obj->form != NULL)
  89.     { fl_error("fl_free_object","Freeing non-deleted object."); fl_delete_object(obj);}
  90.   /* free object */
  91.   if (obj->label != NULL) free(obj->label);
  92.   if (obj->shortcut != NULL) free(obj->shortcut);
  93.   fl_handle_object(obj, FL_FREEMEM, 0.0, 0.0, 0);
  94.   free(obj);
  95. }
  96.  
  97. void fl_free_form(FL_FORM *form)
  98. /* Frees the memory used by an form, together with all its objects. */
  99. {
  100.   FL_OBJECT *current, *next;
  101.   /* check whether ok to free */
  102.   if (form == NULL)
  103.     { fl_error("fl_free_form","Trying to free NULL form."); return;}
  104.   if (form->visible)
  105.     { fl_error("fl_free_form","Freeing visible form.");  fl_hide_form(form);}
  106.   /* free the objects */
  107.   for(next = form->first; next != NULL; )
  108.   {
  109.     current = next;
  110.     next = current->next;
  111.     if (current->label != NULL) free(current->label);
  112.     if (current->shortcut != NULL) free(current->shortcut);
  113.     fl_handle_object(current, FL_FREEMEM, 0.0, 0.0, 0);
  114.     free(current);
  115.   }
  116.   /* free the form structure */
  117.   free(form);
  118. }
  119.  
  120. void fl_add_object(FL_FORM *form, FL_OBJECT *obj)
  121. /* Adds an object to the form. */
  122. {
  123.   /* Checking for correct behaviour. */
  124.   if (obj == NULL)
  125.     { fl_error("fl_add_object","Trying to add NULL object."); return;}
  126.   if (form == NULL)
  127.     { fl_error("fl_add_object","Trying to add object to NULL form."); return;}
  128.   obj->prev = obj->next = NULL;
  129.   if (form->first == NULL)
  130.     form->first = form->last = obj;
  131.   else
  132.   {
  133.     obj->prev = form->last;
  134.     form->last->next = obj;
  135.     form->last = obj;
  136.   }
  137.   obj->form = form;
  138.   if (obj->input && form->focusobj == NULL) fl_set_object_focus(form,obj);
  139.   fl_redraw_object(obj);
  140. }
  141.  
  142. void fl_insert_object(FL_OBJECT *obj, FL_OBJECT *before)
  143. /* Insert object obj before object before. */
  144. {
  145.   FL_FORM *form;
  146.   /* Checking for correct behaviour. */
  147.   if (obj == NULL)
  148.     { fl_error("fl_insert_object","Trying to insert NULL object."); return;}
  149.   if (before == NULL)
  150.     { fl_error("fl_insert_object","Trying to insert before NULL object."); return;}
  151.   if (before->form == NULL)
  152.     { fl_error("fl_insert_object","Trying to insert object to NULL form."); return;}
  153.   form = before->form;
  154.   obj->next = before;
  155.   if (before == form->first)
  156.     { form->first = obj; obj->prev = NULL; }
  157.   else
  158.     { obj->prev = before->prev; obj->prev->next = obj;}
  159.   before->prev = obj;
  160.   obj->form = form;
  161.   if (obj->input && form->focusobj == NULL) fl_set_object_focus(form,obj);
  162.   fl_redraw_form(form);
  163. }
  164.  
  165. void fl_delete_object(FL_OBJECT *obj)
  166. /* Deletes an object from its form. */
  167. {
  168.   FL_FORM *form;
  169.   if (obj == NULL)
  170.     { fl_error("fl_delete_object","Trying to delete NULL object."); return;}
  171.   if (obj->form == NULL)
  172.     { fl_error("fl_delete_object","Trying to delete from NULL form."); return;}
  173.   form = obj->form;
  174.   if (obj->focus) fl_set_object_focus(form,NULL);
  175.   obj->form = NULL;
  176.   if (obj->prev != NULL)
  177.     obj->prev->next = obj->next;
  178.   else
  179.     form->first = obj->next;
  180.   if (obj->next != NULL)
  181.     obj->next->prev = obj->prev;
  182.   else
  183.     form->last = obj->prev;
  184.   if (form->focusobj == NULL)
  185.     fl_set_object_focus(form,fl_find_first(form,FL_FIND_INPUT,0.,0.));
  186.   fl_redraw_form(form);
  187. }
  188.  
  189. /*-----------------------------------------------------------------------
  190.    Setting Attributes.
  191. -----------------------------------------------------------------------*/
  192.  
  193. void fl_set_object_boxtype(FL_OBJECT *ob,int boxtype)
  194. /* Sets the boxtype of the object */
  195. {
  196.   if (ob == NULL)
  197.     { fl_error("fl_set_object_boxtype","Setting boxtype of NULL object."); return;}
  198.   ob->boxtype = boxtype;
  199.   fl_redraw_object(ob);
  200. }
  201.  
  202. void fl_set_object_color(FL_OBJECT *ob,int col1,int col2)
  203. /* Sets the color of the object */
  204. {
  205.   if (ob == NULL)
  206.     { fl_error("fl_set_object_color","Setting color of NULL object."); return;}
  207.   ob->col1 = col1;
  208.   ob->col2 = col2;
  209.   fl_redraw_object(ob);
  210. }
  211.  
  212. void fl_set_object_label(FL_OBJECT *ob, const char *label)
  213. /* sets the label of an object */
  214. {
  215.   if (ob == NULL)
  216.     { fl_error("fl_set_object_label","Setting label of NULL object."); return;}
  217.   if(label) /*TC */
  218.   ob->label = (char *) realloc(ob->label,strlen(label)+1);
  219.   strcpy(ob->label,label ? label:""); /*TC */
  220.   fl_redraw_object(ob);
  221. }
  222.  
  223. void fl_set_object_lcol(FL_OBJECT *ob,int lcol)
  224. /* sets the label color of an object */
  225. {
  226.   if (ob == NULL)
  227.     { fl_error("fl_set_object_lcol","Setting label color of NULL object."); return;}
  228.   ob->lcol = lcol;
  229.   fl_redraw_object(ob);
  230. }
  231.  
  232. void fl_set_object_lsize(FL_OBJECT *ob,float lsize)
  233. /* sets the label size of an object */
  234. {
  235.   if (ob == NULL)
  236.     { fl_error("fl_set_object_lsize","Setting label size of NULL object."); return;}
  237.   ob->lsize = lsize;
  238.   fl_redraw_object(ob);
  239. }
  240.  
  241. void fl_set_object_lstyle(FL_OBJECT *ob,int lstyle)
  242. /* sets the label style of an object */
  243. {
  244.   if (ob == NULL)
  245.     { fl_error("fl_set_object_lstyle","Setting label style of NULL object."); return;}
  246.   ob->lstyle = lstyle;
  247.   fl_redraw_object(ob);
  248. }
  249.  
  250. void fl_set_object_align(FL_OBJECT *ob,int align)
  251. /* sets the label alignment of an object */
  252. {
  253.   if (ob == NULL)
  254.     { fl_error("fl_set_object_align","Setting label alignment of NULL object."); return;}
  255.   ob->align = align;
  256.   fl_redraw_object(ob);
  257. }
  258.  
  259. void fl_activate_object(FL_OBJECT *ob)
  260. /* makes an object active if it was deactivated by fl_deactivate_object */
  261. {
  262.   FL_OBJECT *obj = ob;
  263.   if (ob == NULL)
  264.     { fl_error("fl_activate_object","Trying to activate NULL object."); return;}
  265.   if (ob->objclass == FL_BEGIN_GROUP)
  266.     while ( ob != NULL && ob->objclass != FL_END_GROUP)
  267.     {
  268.       if (ob->active < 0 ) ob->active = 1;
  269.       if (ob->input && ob->form->focusobj == NULL)
  270.         fl_set_object_focus(ob->form,ob);
  271.       ob = ob->next;
  272.     }
  273.   else
  274.   {
  275.     if (ob->active < 0 ) ob->active = 1;
  276.     if (ob->input && ob->form->focusobj == NULL)
  277.       fl_set_object_focus(ob->form,ob);
  278.   }
  279. }
  280.  
  281. void fl_deactivate_object(FL_OBJECT *ob)
  282. /* Deactivates an object */
  283. {
  284.   FL_OBJECT *obj = ob;
  285.   if (ob == NULL)
  286.     { fl_error("fl_deactive_object","Trying to deactive NULL object."); return;}
  287.   if (ob->objclass == FL_BEGIN_GROUP)
  288.     while ( ob != NULL && ob->objclass != FL_END_GROUP)
  289.     {
  290.       if (ob->active > 0 ) ob->active = -1;
  291.       if (ob == ob->form->focusobj )
  292.         fl_set_object_focus(ob->form,
  293.         fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
  294.       ob = ob->next;
  295.     }
  296.   else
  297.   {
  298.     if (ob->active > 0 ) ob->active = -1;
  299.     if (ob == ob->form->focusobj )
  300.       fl_set_object_focus(ob->form,
  301.         fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
  302.   }
  303. }
  304.  
  305. void fl_show_object(FL_OBJECT *ob)
  306. /* makes an object visible */
  307. {
  308.   FL_OBJECT *obj = ob;
  309.   if (ob == NULL)
  310.     { fl_error("fl_show_object","Trying to show NULL object."); return;}
  311.   if (ob->objclass == FL_BEGIN_GROUP)
  312.     while ( ob != NULL && ob->objclass != FL_END_GROUP)
  313.     {
  314.       ob->visible = 1;
  315.       if (ob->input && ob->form->focusobj == NULL)
  316.         fl_set_object_focus(ob->form,ob);
  317.       ob = ob->next;
  318.     }
  319.   else
  320.   {
  321.     ob->visible = 1;
  322.     if (ob->input && ob->form->focusobj == NULL)
  323.       fl_set_object_focus(ob->form,ob);
  324.   }
  325.   fl_redraw_object(obj);
  326. }
  327.  
  328. void fl_hide_object(FL_OBJECT *ob)
  329. /* makes an object invisible */
  330. {
  331.   FL_OBJECT *obj = ob;
  332.   if (ob == NULL)
  333.     { fl_error("fl_hide_object","Trying to hide NULL object."); return;}
  334.   if (ob->objclass == FL_BEGIN_GROUP)
  335.     while ( ob != NULL && ob->objclass != FL_END_GROUP)
  336.     {
  337.       ob->visible = 0;
  338.       if (ob == ob->form->focusobj )
  339.         fl_set_object_focus(ob->form,
  340.         fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
  341.       ob = ob->next;
  342.     }
  343.   else
  344.   {
  345.     ob->visible = 0;
  346.     if (ob == ob->form->focusobj )
  347.       fl_set_object_focus(ob->form,
  348.         fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
  349.   }
  350.   fl_redraw_form(obj->form);
  351. }
  352.  
  353. void fl_set_object_shortcut(FL_OBJECT *obj, const char *str)
  354. /* Sets the list of shortcuts for the object */
  355. {
  356.   char sc[512];
  357.   int i=0, j=0, offset=0;
  358.   if (obj == NULL)
  359.     { fl_error("fl_set_object_shortcut","Object is NULL."); return;}
  360.   while (str[i] != '\0')
  361.   {
  362.     if (str[i] == '#')
  363.     {
  364.       offset = 128;
  365.     }
  366.     else if (str[i] == '^')
  367.     {
  368.       i++;
  369.       if (str[i] >= 'A' && str[i] <= 'Z') sc[j++] = str[i]-'A'+1 + offset;
  370.       else if (str[i] >= 'a' && str[i] <= 'z') sc[j++] = str[i]-'a'+1 + offset;
  371.       else sc[j++] = str[i] + offset;
  372.       offset = 0;
  373.     }
  374.     else
  375.     {
  376.       sc[j++] = str[i] + offset;
  377.       offset = 0;
  378.     }
  379.     i++;
  380.   }
  381.   sc[j] = '\0';
  382.   obj->shortcut = (char *) realloc(obj->shortcut,strlen(sc)+1);
  383.   strcpy(obj->shortcut,sc);
  384.   
  385. }
  386.  
  387. void fl_set_object_focus(FL_FORM *form, FL_OBJECT *obj)
  388. /* Sets the object in the form on which the input is focussed. */
  389. {
  390.   if (form == NULL)
  391.     { fl_error("fl_set_object_focus","Setting focus in NULL form."); return;}
  392.   if (obj == form->focusobj) return;
  393.   fl_handle_object_direct(form->focusobj,FL_UNFOCUS,0.0,0.0,0);
  394.   fl_handle_object_direct(obj,FL_FOCUS,0.0,0.0,0);
  395. }
  396.  
  397. /*-----------------------------------------------------------------------
  398.    Searching in forms
  399. -----------------------------------------------------------------------*/
  400.  
  401. FL_OBJECT *fl_find_object(FL_OBJECT *obj,int find,float mx,float my)
  402. /* returns object in form starting at obj of type find */
  403. {
  404.   while  (obj != NULL)
  405.   {
  406.     if (obj->objclass != FL_BEGIN_GROUP && obj->objclass != FL_END_GROUP &&
  407.       obj->visible && obj->active > 0)
  408.     {
  409.       if (find == FL_FIND_INPUT && obj->input) return obj;
  410.       if (find == FL_FIND_AUTOMATIC && obj->automatic) return obj;
  411.       if (find == FL_FIND_MOUSE && mx >= obj->x && mx <= obj->x+obj->w &&
  412.         my >= obj->y && my <= obj->y + obj->h) return obj;
  413.     }
  414.     obj = obj->next;
  415.   }
  416.   return NULL;
  417. }
  418.  
  419. FL_OBJECT *fl_find_first(FL_FORM *form,int find,float mx,float my)
  420. /* returns the first object of type find */
  421. {
  422.   return ( fl_find_object(form->first,find,mx,my) );
  423. }
  424.  
  425. FL_OBJECT *fl_find_last(FL_FORM *form,int find,float mx,float my)
  426. /* returns the last object of the type find */
  427. {
  428.   FL_OBJECT *last, *obj;
  429.   last = obj = fl_find_first(form,find,mx,my);
  430.   while (obj != NULL)
  431.     { last = obj; obj = fl_find_object(obj->next,find,mx,my); }
  432.   return last;
  433. }
  434.  
  435. /*-----------------------------------------------------------------------
  436.    Drawing Routines.
  437. -----------------------------------------------------------------------*/
  438.  
  439. static void redraw_marked(FL_FORM *form)
  440. /* Redraws all marked objects and reduces the mark */
  441. {
  442.   FL_OBJECT *ob;
  443.   if (!form->visible || form->frozen > 0) return;
  444.   fl_save_user_window();
  445.   fl_set_forms_window(form);
  446.   ob = form->first;
  447.   while (ob != NULL)
  448.   { 
  449.     if (ob->visible && ob->redraw-- > 0) fl_handle_object(ob,FL_DRAW,0.,0.,0);
  450.     ob = ob->next;
  451.   }
  452.   if (form->doublebuf) swapbuffers();
  453.   fl_restore_user_window();
  454. }
  455.  
  456. void fl_redraw_object(FL_OBJECT *obj)
  457. /* The actual drawing routine seen by the user */
  458. {
  459.   FL_OBJECT *ob;
  460.   int drawnumb;
  461.   if (obj == NULL)
  462.     { fl_error("fl_redraw_object","Trying to draw NULL object."); return;}
  463.   if (obj->form == NULL) return;
  464.   if (obj->form->doublebuf) drawnumb = 2; else drawnumb = 1;
  465.   if (obj->objclass == FL_BEGIN_GROUP)
  466.   {
  467.     ob = obj;
  468.     while ( (ob = ob->next) != NULL && ob->objclass != FL_END_GROUP )
  469.       ob->redraw = drawnumb;
  470.   }
  471.   else
  472.     obj->redraw = drawnumb;
  473.   redraw_marked(obj->form);
  474. }
  475.  
  476. void fl_redraw_form(FL_FORM *form)
  477. /* Draws a form */
  478. {
  479.   FL_OBJECT *ob;
  480.   int drawnumb;
  481.   if (form == NULL)
  482.     { fl_error("fl_redraw_form","Drawing NULL form."); return;}
  483.   if (form->doublebuf) drawnumb = 2; else drawnumb = 1;
  484.   ob = form->first;
  485.   while ( ob != NULL )
  486.     { ob->redraw = drawnumb; ob = ob->next; }
  487.   redraw_marked(form);
  488. }
  489.  
  490. void fl_freeze_object(FL_OBJECT *obj)
  491. /* Disables drawing of object */
  492. /* TO BE REMOVED */
  493. {
  494.   fprintf(stderr, "fl_freeze_object() is obsolete. Use fl_freeze_form() instead\n");
  495.   if (obj == NULL)
  496.     { fl_error("fl_freeze_object","Freezing NULL object."); return;}
  497.   fl_freeze_form(obj->form);
  498. }
  499.  
  500. void fl_unfreeze_object(FL_OBJECT *obj)
  501. /* Enable drawing of object */
  502. /* TO BE REMOVED */
  503. {
  504.   fprintf(stderr, "fl_unfreeze_object() is obsolete. Use fl_unfreeze_form() instead\n");
  505.   if (obj == NULL)
  506.     { fl_error("fl_freeze_object","Unfreezing NULL object."); return;}
  507.   fl_unfreeze_form(obj->form);
  508. }
  509.  
  510. void fl_freeze_form(FL_FORM *form)
  511. /* Disables drawing of form */
  512. {
  513.   if (form == NULL)
  514.     { fl_error("fl_freeze_form","Freezing NULL form."); return;}
  515.   form->frozen++;
  516. }
  517.  
  518. void fl_unfreeze_form(FL_FORM *form)
  519. /* Enable drawing of form */
  520. {
  521.   if (form == NULL)
  522.     { fl_error("fl_unfreeze_form","Unfreezing NULL form."); return;}
  523.   if (form->frozen == 0)
  524.     { fl_error("fl_unfreeze_form","Unfreezing non-frozen form."); return;}
  525.   form->frozen--;
  526.   if (form->frozen == 0) redraw_marked(form);
  527. }
  528.  
  529. /*-----------------------------------------------------------------------
  530.    Handling Routines.
  531. -----------------------------------------------------------------------*/
  532.  
  533. static int fl_handle_it(FL_OBJECT *obj,int event,float mx,float my,char key)
  534. /* handles an event for an object */
  535. {
  536.   if (obj == NULL) return 0;
  537.   if (obj->objclass == FL_BEGIN_GROUP || obj->objclass ==FL_END_GROUP) return 0;
  538.   if (obj->handle == NULL) return 0;
  539.   switch (event)
  540.   {
  541.     case FL_ENTER:     obj->belowmouse = 1; break;
  542.     case FL_LEAVE:     obj->belowmouse = 0; break;
  543.     case FL_PUSH:    obj->pushed = 1; break;
  544.     case FL_RELEASE:    if (! obj->radio) obj->pushed = 0; break;
  545.     case FL_FOCUS:     obj->form->focusobj = obj; obj->focus = 1; break;
  546.     case FL_UNFOCUS:    obj->form->focusobj = NULL; obj->focus = 0; break;
  547.   }
  548.   return (*(obj->handle))(obj,event,mx,my,key);
  549. }
  550.  
  551. void fl_handle_object(FL_OBJECT *obj,int event,float mx,float my,char key)
  552. /* handle and store if successfull */
  553.   { if (fl_handle_it(obj,event,mx,my,key)) fl_object_qenter(obj); }
  554.  
  555. int fl_handle_object_direct(FL_OBJECT *obj,int event,float mx,float my,char key)
  556. /* handle but returns whether successfull */
  557.   { return fl_handle_it(obj,event,mx,my,key); }
  558.  
  559. /* TC: added to minimize redraw of forms in single buffer mode*/
  560. void fl_hide_object_only(FL_OBJECT *ob)
  561. {
  562.    long owin = winget();
  563.    int cols;
  564.  
  565.    if(fl_doublebuf) {fl_hide_object(ob); return; }
  566.    if (ob == NULL)
  567.     { fl_error("fl_hide_object_only","Trying to hide NULL object.");
  568. return;}
  569.    if(!ob->visible || !ob->form->visible) {
  570.       fl_hide_object(ob);
  571.       return ;
  572.    }
  573.    /* here, difficult to guess what the form bk color is */
  574.   if(ob->form->first->next->objclass == FL_BOX &&
  575.      ob->form->first->next->type != FL_NO_BOX )
  576.      cols = ob->form->first->next->col1;
  577.   else
  578.      cols = ob->form->first->col1;
  579.   winset(ob->form->window);
  580.   fl_color(cols);
  581.   rectf(ob->x-0.2, ob->y-0.2, ob->x+ob->w-0.8,ob->y+ob->h-0.8);
  582.   fl_drw_text_beside(ob->align, ob->x, ob->y, ob->w, ob->h,
  583.      cols, ob->lsize, ob->lstyle, ob->label);
  584.   ob->visible = 0;
  585.   if(owin > 0) winset(owin);
  586. }
  587.